//
//  ThreadQueue.hpp
// ~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2013-2014 Razvan Coca (razvan dot coca at  gmail dot com)
// This is mostly generated code. Generator is distributed under GPL. Edit it to suit your needs.
// 


#ifndef THREADQUEUE_HPP
#define THREADQUEUE_HPP
#include <boost/noncopyable.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/make_shared.hpp>
#include <memory>

template <class MessageType>
class ThreadQueue:private boost::noncopyable,public boost::enable_shared_from_this<ThreadQueue<MessageType>>
{

    boost::mutex                    mutex;
    boost::condition_variable       full;
    boost::condition_variable       empty;
    const  int                      capacity;
    int                             start;
    int                             end;
    int                             size;
    std::unique_ptr<MessageType[]>  List;
    ThreadQueue(){};
    ThreadQueue(std::size_t capacity=100):
        capacity(capacity),start(0),end(0),size(0),
        List(std::unique_ptr<MessageType[]>(new MessageType[capacity]))
    {}

public:
    static boost::shared_ptr<ThreadQueue<MessageType> > create(std::size_t capacity=100)
    {
        return boost::shared_ptr<ThreadQueue<MessageType>>( new ThreadQueue<MessageType>(capacity));
    }
    ~ThreadQueue(){}
    int put(MessageType const&  msg)
    {
        boost::mutex::scoped_lock lock(mutex);
        while(size==capacity)empty.wait(lock);
        List[start] = msg;
        ++size;
        ++start;
        start %=capacity;
        lock.unlock();
        full.notify_all();
        return 1;
    }
    int get(MessageType& msg)
    {
        boost::mutex::scoped_lock lock(mutex);
        while(size==0)full.wait(lock);
        msg = List[end];
        --size;
        ++end;
        end %= capacity;
        lock.unlock();
        empty.notify_all();
        return 1;
    }
    int len()
    {
        boost::mutex::scoped_lock lock(mutex);
        return size;
    }

};

#endif // THREADQUEUE_HPP
